package cn.hznc.controller.service.inventory;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.constant.CommonConstant;
import cn.hznc.constant.ToolConstant;
import cn.hznc.domain.entity.*;
import cn.hznc.domain.request.inventory.BackupAssemblyToolReq;
import cn.hznc.domain.request.inventory.InBoundOrOutBoundAssemblyReq;
import cn.hznc.domain.request.inventory.InboundToolPartAssemblyToolReq;
import cn.hznc.exception.ToolLifeCycleEx;
import cn.hznc.exception.ToolLifeCycleException;
import cn.hznc.mapper.*;
import cn.hznc.repository.EntryExitRecordRepository;
import cn.hznc.repository.ToolPartRespository;
import cn.hznc.utils.CommonUtil;
import cn.hznc.vo.AssembleLogVo;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author：Administrator
 * @Date：2023/5/5 21:40
 */
@Service
public class ToolPartService {

    @Resource
    private ToolPartRespository ToolPartRespository;

    @Resource
    private ToolForkInfoMapper toolForkInfoMapper;

    @Resource
    private EntryExitRecordRepository entryExitRecordRepository;

    @Resource
    private ToolPartMapper toolPartMapper;

    @Resource
    private ToolConnectMapper toolConnectMapper;

    @Resource
    private AssemblyToolInventoryMapper assemblyToolInventoryMapper;

    @Resource
    private ToolLifeMapper toolLifeMapper;



    private static  final HashMap<String , String> toolCodeMap  = new HashMap<>();

    private static  final HashMap<String , String> assemblyToolCodeMap  = new HashMap<>();

    static {
        toolCodeMap.put("A001B001" , "01");
        toolCodeMap.put("A001B002" , "02");
        toolCodeMap.put("A001B003" , "03");
        toolCodeMap.put("A001B004" , "00");
        assemblyToolCodeMap.put("车削刀具" , "01");
        assemblyToolCodeMap.put("铣削刀具" , "02");
        assemblyToolCodeMap.put("孔加工刀具" , "03");
    }

    public String generateToolUniqueIdPrefix(String code){
        final String[] toolCode = {""};
        toolCodeMap.forEach((key, value) -> {
            if (StringUtil.isNotEmpty(code) && code.startsWith(key)) {
                 toolCode[0] = value;
            }
        });
        return ToolConstant.SN_TOOL_PREFIX + toolCode[0];
    }

    public String generateAssemblyToolUniqueIdPrefix(String code){
        final String[] assemblyToolCode = {""};
        assemblyToolCodeMap.forEach((key, value) -> {
            if (StringUtil.isNotEmpty(code) && code.startsWith(key)) {
                assemblyToolCode[0] = value;
            }
        });
        return ToolConstant.SN_ASSEMBLY_TOOL_PREFIX + assemblyToolCode[0];
    }

    public String generateTimeCode(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(new Date());
    }

    /**
     * 库位刀具零件按类型入库时自动分配单个零件唯一id
     *
     * @param toolInventoryLocationEntity
     */
    public List<Integer> buildToolUniqueId(ToolInventoryLocationEntity toolInventoryLocationEntity, Integer number , String partno , String life) {
        ToolForkInfoEntity toolForkInfoEntity = toolForkInfoMapper.selectById(toolInventoryLocationEntity.getToolId());
        List<ToolPartEntity> toolPartEntityList = new ArrayList<>();
        for (int i = 0; i < number; i++) {
            ToolPartEntity toolPartEntity = new ToolPartEntity();
            toolPartEntity.setUniqueId(generateToolUniqueIdPrefix(toolForkInfoEntity.getType()) +"."+ toolForkInfoEntity.getPartno()+"."+generateTimeCode()+"." +CommonUtil.randomNumber());
            toolPartEntity.setIdnr(toolForkInfoEntity.getIdnr());
            toolPartEntity.setPartno(toolForkInfoEntity.getPartno());
            toolPartEntity.setToolType(toolForkInfoEntity.getType());
            toolPartEntity.setTypeFlag(CommonConstant.TOOL_TYPE_FLAG);
            //TO DO刀具寿命设置
            if(StringUtil.isEmpty(life)){
                QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
                wrapper.eq("classify" , toolPartEntity.getPartno());
                wrapper.eq("type_flag" , 0);
                List<ToolLifeEntity> toolLifeEntity = toolLifeMapper.selectList(wrapper);
                if(CollectionUtil.isNotEmpty(toolLifeEntity)){
                    toolPartEntity.setLife(toolLifeEntity.get(0).getLife() + "h");
                    toolPartEntity.setRemainingLife(toolLifeEntity.get(0).getLife() + "h");
                    toolPartEntity.setTimeUsage("0h");
                    toolPartEntity.setRemainingLifeRate((long)100);
                }else {
                    toolPartEntity.setLife("200h");
                    toolPartEntity.setRemainingLife("200h");
                    toolPartEntity.setTimeUsage("0h");
                    toolPartEntity.setRemainingLifeRate((long)100);
                }
            }else{
                toolPartEntity.setLife("200h");
                toolPartEntity.setRemainingLife("200h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }
            toolPartEntity.setImage(toolForkInfoEntity.getImage());
            toolPartEntity.setInventoryLocationId(toolInventoryLocationEntity.getInventoryLocationId());
            toolPartEntity.setIsAssembled(0);
            toolPartEntity.setCodeScannerFlag(0);
            toolPartEntity.setSelectedFlag(0);
            toolPartEntity.setIsDamage(CommonConstant.IS_NOT_DAMAGE);
            toolPartEntityList.add(toolPartEntity);
        }
        ToolPartRespository.saveBatch(toolPartEntityList);
        return toolPartEntityList.stream().map(ToolPartEntity::getId).collect(Collectors.toList());
    }

    public List<ToolPartEntity> toolOutBound(ToolForkInfoEntity toolForkInfoEntity, Integer inventoryLocationId, Integer number) {
        List<ToolPartEntity> toolPartEntities = queryToolPartList(toolForkInfoEntity, inventoryLocationId);
        //从集合中取出操作数量的元素
        return  randomOutbound(number, toolPartEntities);
    }

    @NotNull
    private List<ToolPartEntity> randomOutbound(Integer number, List<ToolPartEntity> toolPartEntities) {
        if(CollectionUtil.isEmpty(toolPartEntities)){
            new ArrayList<>();
        }
        List<ToolPartEntity> outBoundList = toolPartEntities.stream()
                .limit(number)
                .collect(Collectors.toList());
        for (ToolPartEntity toolPartEntity : outBoundList) {
            //设置库存单个零件表中库位id字段的值（删除关联关系，设置为null的话批量修改方法不会生成对应的set语句，所以设置为0代替）
            toolPartEntity.setInventoryLocationId(0);
        }
        if(!CollectionUtils.isEmpty(outBoundList)){
            toolPartMapper.updateBatchById(outBoundList);
        }
        return outBoundList;
    }

    private List<ToolPartEntity> queryToolPartList(ToolForkInfoEntity toolForkInfoEntity, Integer inventoryLocationId) {
        QueryWrapper<ToolPartEntity> wrapper = new QueryWrapper<>();
        //wrapper.eq("idnr", toolForkInfoEntity.getIdnr());
        wrapper.eq("partno", toolForkInfoEntity.getPartno());
        wrapper.eq("inventory_location_id", inventoryLocationId);
        wrapper.eq("is_damage" , 0);
        return toolPartMapper.selectList(wrapper);
    }

    public List<ToolPartEntity> buildAssemblyUniqueId(ToolInventoryLocationEntity toolInventoryLocationEntity, InBoundOrOutBoundAssemblyReq inBoundOrOutBoundAssemblyReq, AssemblyToolInventoryEntity assemblyToolInventoryEntity) throws ToolLifeCycleException {
        List<ToolPartEntity> toolPartEntityList = new ArrayList<>();
        for (int i = 0; i < inBoundOrOutBoundAssemblyReq.getNumber(); i++) {
            ToolPartEntity toolPartEntity = new ToolPartEntity();
            String uniqueId = CommonConstant.LABEL_PREFIX+"ASSEMBLYTOOL" + UUID.randomUUID().toString().replaceAll("-", "").substring(0,5)+System.currentTimeMillis();
            toolPartEntity.setUniqueId(uniqueId);
            toolPartEntity.setInventoryLocationId(toolInventoryLocationEntity.getInventoryLocationId());
            toolPartEntity.setToolNo(assemblyToolInventoryEntity.getToolNo());
            toolPartEntity.setIsDamage(CommonConstant.IS_NOT_DAMAGE);
            //TO DO 刀具寿命设置
            toolPartEntity.setLife("200h");
            toolPartEntity.setRemainingLife("200h");
            buildAssemlyMaterialList(inBoundOrOutBoundAssemblyReq, assemblyToolInventoryEntity, toolPartEntity , uniqueId);
            toolPartEntityList.add(toolPartEntity);
        }
        ToolPartRespository.saveBatch(toolPartEntityList);
        return toolPartEntityList;
    }

    private void buildAssemlyMaterialList(InBoundOrOutBoundAssemblyReq inBoundOrOutBoundAssemblyReq, AssemblyToolInventoryEntity assemblyToolInventoryEntity, ToolPartEntity toolPartEntity , String uniqueId) throws ToolLifeCycleException {
        QueryWrapper<ToolConnectEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("tool_no" , inBoundOrOutBoundAssemblyReq.getToolNo());
        ToolConnectEntity toolConnectEntity = toolConnectMapper.selectOne(wrapper);
        if(ObjectUtil.isNull(toolConnectEntity)){
            throw new ToolLifeCycleException(ToolLifeCycleEx.CUTTER_NOT_EXIST.getCode(), ToolLifeCycleEx.CUTTER_NOT_EXIST.getMsg());
        }
        //找到类型为输入刀片类型最近的一条出库记录，并随机取出一个刀片封装到具体总成材料清单中（产品需求）
        Integer id = entryExitRecordRepository.getOutboundRecordByType(toolConnectEntity.getPartType());
        List<String> uniqueIds = entryExitRecordRepository.getToolPartList(id);
        if(CollectionUtils.isEmpty(uniqueIds)){
            throw new ToolLifeCycleException(ToolLifeCycleEx.OUTBOUND_RECORD_NOT_FOUND.getCode(), ToolLifeCycleEx.OUTBOUND_RECORD_NOT_FOUND.getMsg());
        }
        //修改组成总成的零件的组装状态
        String toolUniqueId = uniqueIds.get(0);
        String shankUniqueId = inBoundOrOutBoundAssemblyReq.getShankId();
        buildToolPart(toolPartEntity, uniqueId, getToolPart(toolUniqueId), getToolPart(shankUniqueId));
    }

    public void buildAssemlyMaterialList2(List<ToolPartEntity> outboundToolList, List<ToolPartEntity> outboundShankList, ToolPartEntity toolPartEntity , String uniqueId , String operator){
        outboundToolList.forEach(toolEntity -> {
            toolEntity.setIsAssembled(1);
            toolEntity.setInventoryLocationId(-1);
            toolEntity.setAssemblyToolUniqueId(uniqueId);
            //设置总成组装日志
            buildAssembleLog(toolEntity , operator);
            //设置零件组装历史日志
            buildHistoryLog(uniqueId, toolEntity);
        });
        outboundShankList.forEach(shankEntity ->{
            shankEntity.setIsAssembled(1);
            shankEntity.setInventoryLocationId(-1);
            shankEntity.setAssemblyToolUniqueId(uniqueId);
            buildAssembleLog(shankEntity , operator);
            buildHistoryLog(uniqueId, shankEntity);
        });
        toolPartMapper.updateBatchById(Stream.concat(outboundToolList.stream(), outboundShankList.stream()).collect(Collectors.toList()));
        //设置总成材料清单
        Map<String ,Object> paramMap = new HashMap<>();
        paramMap.put("toolType" , outboundToolList.stream().map(ToolPartEntity::getUniqueId).collect(Collectors.toList()));
        paramMap.put("shankType" , outboundShankList.stream().map(ToolPartEntity::getUniqueId).collect(Collectors.toList()));
        toolPartEntity.setParams(JSONObject.toJSONString(paramMap));
        //设置状态为使用中，组装状态
        toolPartEntity.setStatus(0);
        //buildAssembleLog(toolPartEntity , operator);
    }

    private static void buildHistoryLog(String uniqueId, ToolPartEntity toolEntity) {
        List<String> list = new ArrayList<>();
        if (StringUtil.isNotEmpty(toolEntity.getAssemblyUniqueIdHistory())){
            //先前有装配记录
           list = JSONArray.parseArray(toolEntity.getAssemblyUniqueIdHistory() , String.class);
           list.add(uniqueId);
        }
        list.add(uniqueId);
        toolEntity.setAssemblyUniqueIdHistory(JSONArray.toJSONString(list));
    }

    public void buildAssembleLog(ToolPartEntity toolEntity , String operator) {
        AssembleLogVo assembleLogVo = new AssembleLogVo();
        assembleLogVo.setOperator(operator);
        assembleLogVo.setType(CommonConstant.ASSEMBLE_TYPE);
        assembleLogVo.setCreateTime(new Date());
        if(StringUtil.isEmpty(toolEntity.getLog()) || "[]".equals(toolEntity.getLog())){
            //之前无装配记录
            List<AssembleLogVo> list = new ArrayList<>();
            list.add(assembleLogVo);
            toolEntity.setLog(JSONArray.toJSONString(list));
            return;
        }
        //之前有装配记录
        List<AssembleLogVo> assembleLogVos = JSONArray.parseArray(toolEntity.getLog(), AssembleLogVo.class);
        assembleLogVos.add(assembleLogVo);
        toolEntity.setLog(JSONArray.toJSONString(assembleLogVos));
    }

    public void buildUnAssembleLog(ToolPartEntity toolEntity , String operator) {
        AssembleLogVo assembleLogVo = new AssembleLogVo();
        assembleLogVo.setOperator(operator);
        assembleLogVo.setType(CommonConstant.UN_ASSEMBLE_TYPE);
        assembleLogVo.setCreateTime(new Date());
        if(StringUtil.isEmpty(toolEntity.getLog()) || "[]".equals(toolEntity.getLog())){
            //之前无装配记录
            List<AssembleLogVo> list = new ArrayList<>();
            list.add(assembleLogVo);
            toolEntity.setLog(JSONArray.toJSONString(list));
            return;
        }
        //之前有装配记录
        List<AssembleLogVo> assembleLogVos = JSONArray.parseArray(toolEntity.getLog(), AssembleLogVo.class);
        assembleLogVos.add(assembleLogVo);
        toolEntity.setLog(JSONArray.toJSONString(assembleLogVos));
    }

    private void buildToolPart(ToolPartEntity toolPartEntity, String uniqueId, ToolPartEntity toolEntity, ToolPartEntity shankEntity) {
        toolEntity.setIsAssembled(1);
        toolEntity.setInventoryLocationId(0);
        toolEntity.setAssemblyToolUniqueId(uniqueId);
        shankEntity.setIsAssembled(1);
        shankEntity.setInventoryLocationId(0);
        shankEntity.setAssemblyToolUniqueId(uniqueId);
        toolPartMapper.updateBatchById(Arrays.asList(toolEntity, shankEntity));
        //设置总成材料清单
        Map<String ,Object> paramMap = new HashMap<>();
        paramMap.put("toolType" , toolEntity.getUniqueId());
        paramMap.put("shankType" , shankEntity.getUniqueId());
        toolPartEntity.setParams(JSONObject.toJSONString(paramMap));
    }

    private ToolPartEntity getToolPart(String uniqueId) {
        QueryWrapper<ToolPartEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("unique_id" , uniqueId);
        return  toolPartMapper.selectOne(wrapper);
    }

    public List<ToolPartEntity> outAssemblyTool(AssemblyToolInventoryEntity assemblyToolInventoryEntity, Integer inventoryLocationId, Integer number) {
//        QueryWrapper<ToolPartEntity> wrapper = new QueryWrapper<>();
//        wrapper.eq("tool_no" , assemblyToolInventoryEntity.getToolNo());
//        wrapper.eq("inventory_location_id" , inventoryLocationId);
//        List<ToolPartEntity> toolPartEntities = toolPartMapper.selectList(wrapper);
        List<ToolPartEntity> toolPartEntities = ToolPartRespository.selectListByLocationIdAndToolNo(assemblyToolInventoryEntity.getToolNo() , inventoryLocationId);
        return randomOutbound(number, toolPartEntities);
    }

    public List<ToolPartEntity> buildAssemblyToolPart(ToolInventoryLocationEntity toolInventoryLocationEntity , InboundToolPartAssemblyToolReq inboundToolPartAssemblyToolReq , AssemblyToolInventoryEntity assemblyToolInventoryEntity , List<ToolPartEntity> outboundToolList , List<ToolPartEntity> outboundShankList){
        List<ToolPartEntity> toolPartEntityList = new ArrayList<>();
        //按照数量将集合分割
        List<List<ToolPartEntity>> subToolList = CommonUtil.subList(outboundToolList, inboundToolPartAssemblyToolReq.getToolNumber() * inboundToolPartAssemblyToolReq.getNumber());
        List<List<ToolPartEntity>> subShankList = CommonUtil.subList(outboundShankList, inboundToolPartAssemblyToolReq.getShankNumber() * inboundToolPartAssemblyToolReq.getNumber());
        for (int i = 0; i < inboundToolPartAssemblyToolReq.getNumber(); i++) {
            ToolPartEntity toolPartEntity = new ToolPartEntity();
            String uniqueId = generateAssemblyToolUniqueIdPrefix(assemblyToolInventoryEntity.getType())+"."+assemblyToolInventoryEntity.getToolNo() + "." + generateTimeCode()+"."+CommonUtil.randomNumber();
            toolPartEntity.setUniqueId(uniqueId);
            toolPartEntity.setInventoryLocationId(toolInventoryLocationEntity.getInventoryLocationId());
            toolPartEntity.setToolNo(assemblyToolInventoryEntity.getToolNo());
            toolPartEntity.setIsDamage(CommonConstant.IS_NOT_DAMAGE);
            toolPartEntity.setTypeFlag(CommonConstant.ASSEMBLY_TOOL_TYPE_FLAG);
            toolPartEntity.setImage(assemblyToolInventoryEntity.getImage());
            toolPartEntity.setSelectedFlag(0);
            //TO DO 刀具寿命设置
            QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("classify" , toolPartEntity.getToolNo());
            wrapper.eq("type_flag" , 1);
            ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
            if(ObjectUtil.isNotNull(toolLifeEntity)) {
                toolPartEntity.setLife(toolLifeEntity.getLife() + "h");
                toolPartEntity.setRemainingLife(toolLifeEntity.getLife() + "h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }else {
                toolPartEntity.setLife("200h");
                toolPartEntity.setRemainingLife("200h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }
            buildAssembleLog(toolPartEntity , inboundToolPartAssemblyToolReq.getOperator());
            buildAssemlyMaterialList2(subToolList.get(i) , subShankList.get(i) , toolPartEntity , uniqueId , inboundToolPartAssemblyToolReq.getOperator());
            toolPartEntityList.add(toolPartEntity);
        }
        ToolPartRespository.saveBatch(toolPartEntityList);
        return toolPartEntityList;
    }

    public List<ToolPartEntity> buildAssemblyToolPartReload(ToolInventoryLocationEntity toolInventoryLocationEntity , Integer number , Integer toolNumber , Integer shankNumber ,String operator , AssemblyToolInventoryEntity assemblyToolInventoryEntity , List<ToolPartEntity> outboundToolList , List<ToolPartEntity> outboundShankList){
        List<ToolPartEntity> toolPartEntityList = new ArrayList<>();
        //按照数量将集合分割
        List<List<ToolPartEntity>> subToolList = CommonUtil.subList(outboundToolList, toolNumber * number);
        List<List<ToolPartEntity>> subShankList = CommonUtil.subList(outboundShankList, shankNumber * number);
        for (int i = 0; i < number; i++) {
            ToolPartEntity toolPartEntity = new ToolPartEntity();
            String uniqueId = generateAssemblyToolUniqueIdPrefix(assemblyToolInventoryEntity.getType())+"."+assemblyToolInventoryEntity.getToolNo() + "." + generateTimeCode()+"."+CommonUtil.randomNumber();
            toolPartEntity.setUniqueId(uniqueId);
            toolPartEntity.setInventoryLocationId(toolInventoryLocationEntity.getInventoryLocationId());
            toolPartEntity.setToolNo(assemblyToolInventoryEntity.getToolNo());
            toolPartEntity.setIsDamage(CommonConstant.IS_NOT_DAMAGE);
            toolPartEntity.setTypeFlag(CommonConstant.ASSEMBLY_TOOL_TYPE_FLAG);
            toolPartEntity.setImage(assemblyToolInventoryEntity.getImage());
            toolPartEntity.setSelectedFlag(0);
            //TO DO 刀具寿命设置
            QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("classify" , toolPartEntity.getToolNo());
            wrapper.eq("type_flag" , 1);
            ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
            if(ObjectUtil.isNotNull(toolLifeEntity)) {
                toolPartEntity.setLife(toolLifeEntity.getLife() + "h");
                toolPartEntity.setRemainingLife(toolLifeEntity.getLife() + "h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }else {
                toolPartEntity.setLife("200h");
                toolPartEntity.setRemainingLife("200h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }
            buildAssembleLog(toolPartEntity , operator);
            buildAssemlyMaterialList2(subToolList.get(i) , subShankList.get(i) , toolPartEntity , uniqueId , operator);
            toolPartEntityList.add(toolPartEntity);
        }
        ToolPartRespository.saveBatch(toolPartEntityList);
        return toolPartEntityList;
    }

    public List<ToolPartEntity> buildAssemblyTool(Integer locationId , Integer number , Integer toolNumber , Integer shankNumber ,String operator , AssemblyToolInventoryEntity assemblyToolInventoryEntity , List<ToolPartEntity> outboundToolList , List<ToolPartEntity> outboundShankList){
        List<ToolPartEntity> toolPartEntityList = new ArrayList<>();
        //按照数量将集合分割
        List<List<ToolPartEntity>> subToolList = CommonUtil.subList(outboundToolList, toolNumber * number);
        List<List<ToolPartEntity>> subShankList = CommonUtil.subList(outboundShankList, shankNumber * number);
        for (int i = 0; i < number; i++) {
            ToolPartEntity toolPartEntity = new ToolPartEntity();
            String uniqueId = generateAssemblyToolUniqueIdPrefix(assemblyToolInventoryEntity.getType())+"."+assemblyToolInventoryEntity.getToolNo() + "." + generateTimeCode()+"."+CommonUtil.randomNumber();
            toolPartEntity.setUniqueId(uniqueId);
            toolPartEntity.setInventoryLocationId(locationId);
            toolPartEntity.setToolNo(assemblyToolInventoryEntity.getToolNo());
            toolPartEntity.setIsDamage(CommonConstant.IS_NOT_DAMAGE);
            toolPartEntity.setTypeFlag(CommonConstant.ASSEMBLY_TOOL_TYPE_FLAG);
            toolPartEntity.setImage(assemblyToolInventoryEntity.getImage());
            toolPartEntity.setSelectedFlag(0);
            //TO DO 刀具寿命设置
            QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("classify" , toolPartEntity.getToolNo());
            wrapper.eq("type_flag" , 1);
            ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
            if(ObjectUtil.isNotNull(toolLifeEntity)) {
                toolPartEntity.setLife(toolLifeEntity.getLife() + "h");
                toolPartEntity.setRemainingLife(toolLifeEntity.getLife() + "h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }else {
                toolPartEntity.setLife("200h");
                toolPartEntity.setRemainingLife("200h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }
            buildAssembleLog(toolPartEntity , operator);
            buildAssemlyMaterialList2(subToolList.get(i) , subShankList.get(i) , toolPartEntity , uniqueId , operator);
            toolPartEntityList.add(toolPartEntity);
        }
        ToolPartRespository.saveBatch(toolPartEntityList);
        return toolPartEntityList;
    }

    public List<ToolPartEntity> buildAssemblyToolPartReload(ToolInventoryLocationEntity toolInventoryLocationEntity , Integer number , String operator,AssemblyToolInventoryEntity assemblyToolInventoryEntity , List<ToolPartEntity> toolPartEntities){
        List<ToolPartEntity> toolPartEntityList = new ArrayList<>();
        //按照数量将集合分割
        for (int i = 0; i < number; i++) {
            ToolPartEntity toolPartEntity = new ToolPartEntity();
            String uniqueId = generateAssemblyToolUniqueIdPrefix(assemblyToolInventoryEntity.getType())+"."+assemblyToolInventoryEntity.getToolNo() + "." + generateTimeCode()+"."+CommonUtil.randomNumber();
            toolPartEntity.setUniqueId(uniqueId);
            toolPartEntity.setInventoryLocationId(toolInventoryLocationEntity.getInventoryLocationId());
            toolPartEntity.setToolNo(assemblyToolInventoryEntity.getToolNo());
            toolPartEntity.setIsDamage(CommonConstant.IS_NOT_DAMAGE);
            toolPartEntity.setTypeFlag(CommonConstant.ASSEMBLY_TOOL_TYPE_FLAG);
            toolPartEntity.setImage(assemblyToolInventoryEntity.getImage());
            toolPartEntity.setSelectedFlag(0);
            //TO DO 刀具寿命设置
            QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("classify" , toolPartEntity.getToolNo());
            wrapper.eq("type_flag" , 1);
            ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
            if(ObjectUtil.isNotNull(toolLifeEntity)) {
                toolPartEntity.setLife(toolLifeEntity.getLife() + "h");
                toolPartEntity.setRemainingLife(toolLifeEntity.getLife() + "h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }else {
                toolPartEntity.setLife("200h");
                toolPartEntity.setRemainingLife("200h");
                toolPartEntity.setTimeUsage("0h");
                toolPartEntity.setRemainingLifeRate((long)100);
            }
            buildAssembleLog(toolPartEntity , operator);
            buildAssemlyMaterialList2Reload(toolPartEntities, toolPartEntity , uniqueId , operator);
            toolPartEntityList.add(toolPartEntity);
        }
        ToolPartRespository.saveBatch(toolPartEntityList);
        return toolPartEntityList;
    }

    private void buildAssemlyMaterialList2Reload(List<ToolPartEntity> toolPartEntities, ToolPartEntity toolPartEntity, String uniqueId, String operator) {
        toolPartEntities.forEach(toolEntity -> {
            toolEntity.setIsAssembled(1);
            toolEntity.setInventoryLocationId(-1);
            toolEntity.setAssemblyToolUniqueId(uniqueId);
            //设置总成组装日志
            buildAssembleLog(toolEntity , operator);
            //设置零件组装历史日志
            buildHistoryLog(uniqueId, toolEntity);
        });
        toolPartMapper.updateBatchById(toolPartEntities);
        //设置总成材料清单
//        Map<String ,Object> paramMap = new HashMap<>();
//        paramMap.put("toolType" , outboundToolList.stream().map(ToolPartEntity::getUniqueId).collect(Collectors.toList()));
//        paramMap.put("shankType" , outboundShankList.stream().map(ToolPartEntity::getUniqueId).collect(Collectors.toList()));
//        toolPartEntity.setParams(JSONObject.toJSONString(paramMap));
        //设置状态为使用中，组装状态
        toolPartEntity.setStatus(0);
        //buildAssembleLog(toolPartEntity , operator);

    }


    public void backupAssemblyTool(BackupAssemblyToolReq backupAssemblyToolReq) throws ToolLifeCycleException {
        QueryWrapper<AssemblyToolInventoryEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("tool_no" , backupAssemblyToolReq.getToolNo());
        AssemblyToolInventoryEntity assemblyToolInventoryEntity = assemblyToolInventoryMapper.selectOne(wrapper);
        if(ObjectUtil.isNull(assemblyToolInventoryEntity)){
            throw new ToolLifeCycleException(ToolLifeCycleEx.TOOL_NO_EXIST.getCode() , ToolLifeCycleEx.TOOL_NO_EXIST.getMsg());
        }
        if(CollectionUtil.isEmpty(backupAssemblyToolReq.getToolUniqueIds())
                || CollectionUtil.isEmpty(backupAssemblyToolReq.getShankUniqueIds())
                || checkUniqueIds(Stream.concat(backupAssemblyToolReq.getToolUniqueIds().stream(), backupAssemblyToolReq.getShankUniqueIds().stream()))){
            throw new ToolLifeCycleException(ToolLifeCycleEx.TOOL_UNIQUE_ID_NO_EXIST.getCode(), ToolLifeCycleEx.TOOL_UNIQUE_ID_NO_EXIST.getMsg());
        }
        checkUniqueIds(Stream.concat(backupAssemblyToolReq.getToolUniqueIds().stream(), backupAssemblyToolReq.getShankUniqueIds().stream()));
        ToolPartEntity toolEntity = getByUniqueId(backupAssemblyToolReq.getToolUniqueIds().get(0));
        ToolPartEntity shankEntity = getByUniqueId(backupAssemblyToolReq.getShankUniqueIds().get(0));
        ToolPartEntity toolPartEntity = new ToolPartEntity();
        String uniqueId = generateAssemblyToolUniqueIdPrefix(assemblyToolInventoryEntity.getType())+"."+assemblyToolInventoryEntity.getToolNo() + "." + generateTimeCode()+"."+UUID.randomUUID().toString().replaceAll("-", "").substring(0,5);
        toolPartEntity.setUniqueId(uniqueId);
        //toolPartEntity.setInventoryLocationId(toolInventoryLocationEntity.getInventoryLocationId());
        toolPartEntity.setToolNo(assemblyToolInventoryEntity.getToolNo());
        toolPartEntity.setIsDamage(CommonConstant.IS_NOT_DAMAGE);
        toolPartEntity.setTypeFlag(CommonConstant.ASSEMBLY_TOOL_TYPE_FLAG);
        toolPartEntity.setImage(assemblyToolInventoryEntity.getImage());
        toolPartEntity.setBackupStatus(1);
        toolPartEntity.setBackupMachineToolTaskId(backupAssemblyToolReq.getId());
        //TO DO 刀具寿命设置
        QueryWrapper<ToolLifeEntity> toolLifewrapper = new QueryWrapper<>();
        toolLifewrapper.eq("classify" , toolPartEntity.getPartno());
        toolLifewrapper.eq("type_flag" , 1);
        ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(toolLifewrapper);
        if(ObjectUtil.isNotNull(toolLifeEntity)) {
            toolPartEntity.setLife(toolLifeEntity.getLife() + "h");
            toolPartEntity.setRemainingLife(toolLifeEntity.getLife() + "h");
            toolPartEntity.setTimeUsage("0h");
        }else {
            toolPartEntity.setLife("200h");
            toolPartEntity.setRemainingLife("200h");
            toolPartEntity.setTimeUsage("0h");
        }
        buildAssembleLog(toolPartEntity , backupAssemblyToolReq.getOperator());
        buildAssemlyMaterialList2(Arrays.asList(toolEntity) , Arrays.asList(shankEntity) , toolPartEntity , uniqueId , backupAssemblyToolReq.getOperator());
        toolPartMapper.insert(toolPartEntity);
        //入库到备刀货架

    }

    public boolean checkUniqueIds(Stream<String> concat) {
        List<String> collect = concat.collect(Collectors.toList());
        for (int i = 0; i < collect.size(); i++) {
            QueryWrapper<ToolPartEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("unique_id" , collect.get(i));
            ToolPartEntity toolPartEntity = toolPartMapper.selectOne(wrapper);
            if(ObjectUtil.isNull(toolPartEntity)){
                return true;
            }
        }
        return false;
    }

    public ToolPartEntity getByUniqueId(String uniqueId){
        QueryWrapper<ToolPartEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("unique_id" , uniqueId);
        return toolPartMapper.selectOne(wrapper);
    }

    public List<ToolPartEntity> getByUniqueIds(List<String> uniqueIds){
        List<ToolPartEntity> resultList = new ArrayList<>();
        if(CollectionUtil.isEmpty(uniqueIds)){
            return resultList;
        }
        uniqueIds.forEach(uniqueId ->{
            QueryWrapper<ToolPartEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("unique_id" , uniqueId);
            ToolPartEntity toolPartEntity = toolPartMapper.selectOne(wrapper);
            if(ObjectUtil.isNotNull(toolPartEntity)){
                resultList.add(toolPartEntity);
            }
        });
        return resultList;
    }
}
